package com.ctc.test;

import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.ctc.CRC;
import com.ctc.CTCClientConnState;
import com.ctc.CTCEvent;
import com.ctc.CTCMaster;
import com.ctc.test.fragment.BaseFragment;

import androidx.annotation.NonNull;


public class MasterFragment extends BaseFragment implements CTCEvent.IMaster
{
    /** 主设备产品ID */
    private TextView tvMasterProductID;
    /** 主设备ID */
    private TextView tvMasterDeviceID;
    /** 从设备产品ID */
    private TextView tvSlaveProductID;
    /** 从设备ID */
    private TextView tvSlaveDeviceID;
    /** 投币数量 */
    private TextView tvSlaveCoinIn;
    /** 出票数量 */
    private TextView tvSlaveTicketOut;
    /** 连接状态 */
    private TextView tvConnectState;

    /** 打开串口 */
    private Button btnOpenSerial;
    /** 关闭串口 */
    private Button btnCloseSerial;
    /** 读取从设备抄表数据 */
    private Button btnReadMeter;
    /** 投币 */
    private Button btnCoinIn;
    /** 设置币值 */
    private Button btnSetCoinPrice;
    /** 查询币值 */
    private Button btnQueryCoinPrice;
    /** 选择通道 */
    private Button btnSelectChannel;
    /** 变更状态 */
    private Button btnChangeState;
    /**
     * 从设备出票数量
     */
    private long slaveTicketOut;
    /**
     * 从设备投币数量
     */
    private long slaveCoinIn;
    /** 主设备 */
    private CTCMaster ctcMaster;
    /** 主设备产品ID */
    private long masterProductID = 0;
    /** 主设备ID */
    private byte[] masterDeviceID = new byte[16];

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        if (bindView == null)
        {
            bindView = inflater.inflate(R.layout.fragment_master, container, false);
            initMsgList(R.id.fragment_master_list_msg);
            initSerialSpinner(R.id.fragment_master_spinner_serial);
            tvMasterProductID = bindView.findViewById(R.id.fragment_master_tv_masterProductID);
            tvMasterDeviceID = bindView.findViewById(R.id.fragment_master_tv_masterDeviceID);
            tvSlaveProductID = bindView.findViewById(R.id.fragment_master_tv_slaveProductID);
            tvSlaveDeviceID = bindView.findViewById(R.id.fragment_master_tv_slaveDeviceID);
            tvSlaveCoinIn = bindView.findViewById(R.id.fragment_master_tv_slaveCoinIn);
            tvSlaveTicketOut = bindView.findViewById(R.id.fragment_master_tv_slaveTicketOut);
            tvConnectState = bindView.findViewById(R.id.fragment_master_tv_connectState);
            //
            btnOpenSerial = bindView.findViewById(R.id.fragment_master_btn_openSerial);
            btnCloseSerial = bindView.findViewById(R.id.fragment_master_btn_closeSerial);
            btnReadMeter = bindView.findViewById(R.id.fragment_master_btn_readMeter);
            btnCoinIn = bindView.findViewById(R.id.fragment_master_btn_coinIn);
            btnSetCoinPrice = bindView.findViewById(R.id.fragment_master_btn_setCoinPrice);
            btnQueryCoinPrice = bindView.findViewById(R.id.fragment_master_btn_queryCoinPrice);
            btnSelectChannel = bindView.findViewById(R.id.fragment_master_btn_selectChannel);
            btnChangeState = bindView.findViewById(R.id.fragment_master_btn_changeState);
            //
            btnOpenSerial.setOnClickListener(v -> {
                String serialPort = (String) spinnerSerial.getSelectedItem();
                ctcMaster = new CTCMaster(serialPort, masterProductID, masterDeviceID);
                ctcMaster.setListener(this);
                ctcMaster.open();
                v.setEnabled(false);
            });
            btnReadMeter.setOnClickListener(v -> {
                ctcMaster.sendReadMeter();
            });
            btnCoinIn.setOnClickListener(v -> {
                ctcMaster.sendInCoin(1, new byte[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, new byte[]{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2});
            });
            btnSetCoinPrice.setOnClickListener(v -> {
                ctcMaster.sendSetCoinPrice(22);
            });
            btnQueryCoinPrice.setOnClickListener(v -> {
                ctcMaster.sendQueryCoinPrice();
            });
            btnSelectChannel.setOnClickListener(v -> {
                ctcMaster.sendSelectChannel((byte) 0, (byte) 1);
            });
            btnChangeState.setOnClickListener(v -> {
                if (ctcMaster.getMasterState() == 0)
                {
                    ctcMaster.changeState((byte) 1);
                }
                else
                {
                    ctcMaster.changeState((byte) 0);
                }
            });
            btnCloseSerial.setOnClickListener(v -> {
                ctcMaster.close();
                v.setEnabled(false);
                btnOpenSerial.setEnabled(true);
                instEnable(false);
                tvConnectState.setTextColor(Color.BLACK);
            });
            btnCloseSerial.setEnabled(false);
            instEnable(false);
            tvMasterProductID.setText(String.format("MasterProductID:%s", masterProductID));
            tvMasterDeviceID.setText(String.format("MasterDeviceID:%s", CRC.toHexStringTrim(masterDeviceID)));
        }
        return bindView;
    }

    private void instEnable(boolean enable)
    {
//        btnReadMeter.setEnabled(enable);
//        btnCoinIn.setEnabled(enable);
//        btnSetCoinPrice.setEnabled(enable);
//        btnQueryCoinPrice.setEnabled(enable);
//        btnSelectChannel.setEnabled(enable);
//        btnChangeState.setEnabled(enable);
    }

    @Override
    public void onSlaveStateChange(byte player, byte[] data)
    {
        addMsg(String.format("Slave状态变更  %s  %s", data[0], CRC.toHexStringTrim(data[1], data[2])));
    }

    @Override
    public void onMeterData(byte player, byte[] data)
    {
        addMsg(String.format("收到抄表:%s", CRC.toHexStringTrim(data)));
    }

    @Override
    public void onPhysicalReport(byte player, byte[] data)
    {
        byte type = data[0];
        long number = CRC.bytesToUint32(data[1], data[2], data[3], data[4]);
        if (type == 0)
        {
            slaveCoinIn += number;
        }
        addMsg(String.format("实体数据上报:%s   %s", type, number));
        bindView.post(() -> {
            tvSlaveCoinIn.setText(String.format("SlaveCoinIn:%s", slaveCoinIn));
        });
    }

    @Override
    public void onQueryCoin(byte player, byte[] data)
    {
        addMsg(String.format("每局币数:%s", CRC.bytesToUint16(data)));
    }

    @Override
    public void onAtmosphere(byte player, byte[] data)
    {
        long level = CRC.bytesToUint16(data[0], data[1]);
        byte type = data[2];
        long number = CRC.bytesToUint32(data[3], data[4], data[5], data[6]);
        addMsg(String.format("氛围事件:%s   %s   %s", level, type, number));
    }

    @Override
    public void onHandshake(byte player, byte[] data)
    {
        bindView.post(() -> {
            long slaveProductID = CRC.bytesToUint32(data[0], data[1], data[2], data[3]);
            byte[] slaveDeviceID = new byte[16];
            System.arraycopy(data, 4, slaveDeviceID, 0, 16);
            int slaveVersion = CRC.bytesToUint16(data[20], data[21]);
            addMsg(String.format("SlaveVersion:%s", slaveVersion));
            tvSlaveProductID.setText(String.format("SlaveProductID:%s", slaveProductID));
            tvSlaveDeviceID.setText(String.format("SlaveDeviceID:%s", CRC.toHexStringTrim(slaveDeviceID)));
        });
    }

    @Override
    public void onCoinInRsp(byte player, byte[] data)
    {
        byte[] orderID = CRC.subByteData(data, 1, 16);
        addMsg(String.format("卡头投币结果:%s   %s", data[0], CRC.toHexStringTrim(orderID)));
    }

    @Override
    public void onReward(byte player, byte[] data)
    {
        byte type = data[0];
        long number = CRC.bytesToUint32(data[1], data[2], data[3], data[4]);
        if (type == 0)
        {
            slaveTicketOut += number;
        }
        addMsg(String.format("游戏奖励:%s   %s", type, number));
        bindView.post(() -> {
            tvSlaveTicketOut.setText(String.format("SlaveTicketOut:%s", slaveTicketOut));
        });
    }

    @Override
    public void onConnectStateChange(byte player, CTCClientConnState state)
    {
        bindView.post(() -> {
            if (state == CTCClientConnState.Connected)
            {
                tvConnectState.setTextColor(Color.GREEN);
                instEnable(true);
            }
            else
            {
                tvConnectState.setTextColor(Color.RED);
                instEnable(false);
            }
        });
    }

    @Override
    public void onSendSuccess(byte player, byte[] inst, byte[] data)
    {
        addMsg(String.format("发送成功-指令:%s", CRC.toHexStringTrim(inst)));
    }

    @Override
    public void onSendFail(byte state, byte player, byte[] inst, byte[] data)
    {
        addMsg(String.format("发送失败-指令:%s", CRC.toHexStringTrim(inst)));
    }

    @Override
    public void onSerialOpen(byte player, String msg)
    {
        if (msg == null)
        {
            //打开成功
            addMsg("串口打开成功");
            bindView.post(() -> {
                btnCloseSerial.setEnabled(true);
            });
        }
        else
        {
            //打开失败
            bindView.post(() -> {
                btnOpenSerial.setEnabled(true);
                tvConnectState.setTextColor(Color.BLACK);
                instEnable(false);
            });
        }

    }

    @Override
    public void onSerialClose(byte player, String msg)
    {
        //串口被关闭
    }

    @Override
    public void debugLogE(byte player, String msg)
    {
        addMsg(msg);
    }

    @Override
    public void debugLogI(byte player, String msg)
    {
        addMsg(msg);
    }
}
